/*
发布方实现:
  步骤：
      1，包含头文件：
      2，初始化ROS2客户端
      3，定义节点类；
        3-1，创建发布方；
        3-2，创建定时器；
        3-2，组织消息并发布；
      4，调用spin函数，并传入节点对象指针；
      5，释放资源
*/

#include <cstdio>
#include <iostream>
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

using namespace std;
using namespace std::chrono_literals; //用字面量设置后缀的时间单位，设置持续时间

// 3，定义节点类；
class Talker:public rclcpp::Node
{
  public:
    Talker(): //类继承的Node构造函数列表初始化
    Node("talker_node_cpp"),count_(0){
      RCLCPP_INFO(this->get_logger(),"创建发布节点!");
      //  3-1，创建发布方；
      /*
        模板：被发布的消息类型； 如<std_msgs::msg::String>
          1，话题名称；
          2，QOS（消息队列长度）；
          返回值，发布对象指针
      */
      //publisher = this->create_publisher("talker");
      //队列用于在网络阻塞时，消息发不出去的时候，保存在此，待网络恢复了就从此取出再发布
      publisher_ = this->create_publisher<std_msgs::msg::String>("chatter",10);
      
      //  3-3，创建定时器；
      //创建周期为1s的定时器，并利用this对象调用类内的on_timer回调函数
      /*
        参数：
          1，创建时间间隔；
          2，回调函数；
        返回值：定时器对象指针
      */
      timer_ = this->create_wall_timer(0.1s,std::bind(&Talker::on_timer,this));
    }
  private:
    void on_timer()
    {
      //  3-2，组织消息并发布；
      auto message = std_msgs::msg::String();
      message.data = "hello world!"+std::to_string(count_++);
      RCLCPP_INFO(this->get_logger(),"发布方发布消息:%s",message.data.c_str());
      publisher_->publish(message);
    }
    rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
    rclcpp::TimerBase::SharedPtr timer_;
    size_t count_;
};

int main(int argc, char ** argv)
{
  // 2，初始化ROS2客户端
  rclcpp::init(argc,argv);
  
  // 4，调用spin函数，并传入节点对象指针；
  rclcpp:spin(std::make_shared<Talker>());
  // 5，释放资源
  rclcpp::shutdown();
  return 0;
}
